package com.ray.test.mock;

import com.github.jsonzou.jmockdata.JMockData;
import org.springframework.cglib.beans.BeanMap;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author bo shen
 * @Description: 类型
 * @Class: ClassDataMock
 * @Package com.ray.test.mock
 * @date 2019/12/12 14:47
 * @company <p>杭州传化陆鲸科技有限公司</p>
 * @updateRecord time(修改时间)  author(修改人)   desc(修改内容)
 */
public class MapDataMock implements DataMock {
    @Override
    public Object dataMocker(Class<?> clazz, Method method, Parameter parameter) {
        Map<String, Object> data = new HashMap<>();
        for (Map.Entry<String, Class> entry : MockConfig.getDefaultMapFields().entrySet()) {
            data.put(entry.getKey(), JMockData.mock(entry.getValue(), MockConfig.getMockConfig()));
        }
        //把返回对象 转义成参数
        List<Class<?>> clazzs = getReturnTypeClass(method.getGenericReturnType());
        Object value = null;
        for (Class<?> clz : clazzs) {
            value = JMockData.mock(clz, MockConfig.getMockConfig());
            //对象转成map
            if (value != null) {
                BeanMap beanMap = BeanMap.create(value);
                data.putAll(beanMap);
            }
        }
        return data;
    }

    /**
     * 获取成员类的
     *
     * @param type
     * @return
     */
    private List<Class<?>> getReturnTypeClass(Type type) {
        List<Class<?>> clazzs = new ArrayList<>();
        if (ParameterizedType.class.isAssignableFrom(type.getClass())) {
            Class<?> classType = (Class<?>) ((ParameterizedType) type).getRawType();
            if (Iterable.class.isAssignableFrom(classType)) {
                clazzs.add((Class<?>) ((ParameterizedType) type).getActualTypeArguments()[0]);
            } else if (Map.class.isAssignableFrom(classType)) {
                clazzs.add((Class<?>) ((ParameterizedType) type).getActualTypeArguments()[1]);
            }
        } else if((Class<?>) type != void.class ){
            clazzs.add((Class<?>) type);
        }
        return clazzs;
    }
}
